package com.blogspot.oguzhan.game;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;


public class TurnBasedGame extends Game {
	
	private List<Turn> turnHistory;
	private Turn currentTurn;
	private TurnBasedGameEngine gameEngine;
	private int playerOrder;
	
	public TurnBasedGame(int maximumNumberOfPlayers, TurnBasedGameEngine gameEngine) {
		super(maximumNumberOfPlayers);
		this.currentTurn = null;
		this.gameEngine = gameEngine;
		this.turnHistory = new LinkedList<Turn>();
		this.playerOrder = getRandomIndex();
	}

	private int getRandomIndex() {
		return (int) (Math.random() * getNumberOfPlayers()) + 1;
	}
	
	public Player whoIsNext() {
		return getPlayer((playerOrder % super.getNumberOfPlayers()) + 1);
	}
	
	public void makeMove(Move move) {
		validateMove(move);
		gameEngine.move(move);
		updateTurnHistory(move);
		iterateTurn();
	}

	private void iterateTurn() {
		this.playerOrder++;
	}

	private void validateMove(Move move) {
		checkPlayer(move.getOwner());
		
		if (gameEngine.isGameOver()) 
			throw new GameOverNoMoreMoveAllowedException();
		
		if (!whoIsNext().equals(move.getOwner())) 
			throw new ItsNotThisPlayerTurnException();
	}

	private void updateTurnHistory(Move move) {
		if (turnHistory.size() > 0) 
			turnHistory.add(currentTurn);	
		currentTurn = new Turn(turnHistory.size(), move);
	}
	
	public List<Turn> getTurnHistory() {
		List<Turn> copyTurnHistory = new ArrayList<Turn>(turnHistory.size()); 
		Collections.copy(copyTurnHistory, turnHistory);
		return copyTurnHistory;
	}
	
	public static class ItsNotThisPlayerTurnException extends RuntimeException {
		private static final long serialVersionUID = 1L;
	}
	
	public static class GameOverNoMoreMoveAllowedException extends RuntimeException {
		private static final long serialVersionUID = 1L;
	}

}
